using System;
using Gtk;
using System.Collections.Generic;
using DaphneTranslator.BusinessLogic;
using System.IO;

namespace DaphneTranslator
{
	public delegate void TFilenameChangedDelegate(string sOriginalFilePath, string sNewFileName);
	public delegate void TNewCultureDelegate(CultureRecord list);
	
	[System.ComponentModel.ToolboxItem(true)]
	public partial class LanguageListWidget : Gtk.Bin
	{
		private const string colorWhite = "#FFFFFF";
		private const string colorPrimaryLanguage = "#FFFF00";
		
		private const int lNameIndex = 0;
		private const int lKeyIndex = 3;
		
		private List<LangaugeCultureRecord> lstCultureList;
		private string _sPrimaryLanguage;
		private TreeStore _store;
		private CultureCollection _CultureCollection;
		
		private string _sLastSelectedCulture;
		
		public event TFilenameChangedDelegate FilenameChangedEvent;
		public event TNewCultureDelegate NewCultureEvent;
		public event TChangeOccured ChangeOccuredEvent;
		
		public string PrimaryLanguage { 
			get {
				return _sPrimaryLanguage;
			}
			set {
				_sPrimaryLanguage = value;
				UpdatePrimaryLanguageDisplay ();
			}
		}
		
		public LanguageListWidget ()
		{	
			this.Build ();
			
			lstCultureList = new List<LangaugeCultureRecord> ();		
			treeLanguage.ButtonReleaseEvent += HandleButtonReleaseEvent;						
			
			_sLastSelectedCulture = string.Empty;
			
			CreateColumns ();
		}
		
		private void RaiseChangeOccuredEvent ()
		{
			if (ChangeOccuredEvent != null) {
				ChangeOccuredEvent ();
			}
		}

	
		private void LanguageCallback ()
		{
			if (LanguageSelected != null) {
				LanguageSelected (this, EventArgs.Empty);
			}							
		}

		void HandleButtonReleaseEvent (object o, ButtonReleaseEventArgs args)
		{
			if (treeLanguage.Model == null)
				return;			
			if (treeLanguage.Model.IterNChildren () == 0)
				return;	
			
			if (args.Event.Button == 1) {
				string sSelCulture = GetSelectedCulture ();
				if (sSelCulture != _sLastSelectedCulture) {
					_sLastSelectedCulture = sSelCulture;
					LanguageCallback ();
				
				}
			} else if (args.Event.Button == 3) {
				HandlePopupMenu ((int)args.Event.X, (int)args.Event.Y);
			}
		}
		
		void HandlePopupMenu (int x, int y)
		{
			if (treeLanguage.Model == null)
				return;			
			if (treeLanguage.Model.IterNChildren () == 0)
				return;	
			
			Menu menu = new Menu ();
			MenuItem menuNew = new MenuItem ("Create new culture");
			menuNew.Activated += delegate(object sender, EventArgs e) {
				CreateNewCulture ();	
			};
			menu.Append (menuNew);
						
			TreePath path = new TreePath ();
			TreeViewDropPosition drop;
			int tx, ty;						
			treeLanguage.ConvertBinWindowToWidgetCoords (x, y, out tx, out ty);			
			if (treeLanguage.GetDestRowAtPos (tx, ty, out path, out drop) == true) {
			
				menu.Append (new SeparatorMenuItem ());
				
				TreeIter iter;
				_store.GetIter (out iter, path);
				int i = path.Indices [0];			
			
				
				
				MenuItem menuItem = new MenuItem ("Set as primary language");
				menuItem.Activated += delegate {
					menu.Popdown ();
					PrimaryLanguage = GetSelectedCulture ();
					UpdatePrimaryLanguageDisplay ();
					LanguageCallback ();					
				}; 	
				menu.Append (menuItem);
				
				menu.Append (new SeparatorMenuItem ());
				
				menuItem = new MenuItem ("Properties");
				menuItem.Activated += delegate(object sender, EventArgs e) {
				/*	EditProperties (_lstLangLists [i]);
*/				};
				menu.Append (menuItem);
			}
							
			menu.ShowAll ();
			menu.Popup ();						
		}
		
		private void CreateNewCulture ()
		{
			CultureSelectDialog dlg = new CultureSelectDialog ();
			dlg.SetQuestionMessage ("Select culture for new language list:");
			ResponseType res = (ResponseType)dlg.Run ();
			if (res == ResponseType.Apply) {
				string sCulture = dlg.GetSelectedCulture ();
				
				CultureRecord lstNew = new CultureRecord ();
				lstNew.Culture = sCulture;
				lstNew.CultureName = sCulture;
				lstNew.EnglishName = sCulture;
				
				_CultureCollection.CultureList.Add (lstNew);
				SetLangauges (_CultureCollection);					
				
				if (NewCultureEvent != null) {
					NewCultureEvent (lstNew);
				}
				
				RaiseChangeOccuredEvent ();
			}
			
			dlg.Destroy ();
		}
		
		

		public event EventHandler LanguageSelected;

		
		public string GetSelectedCulture ()
		{
			// get selected tree iter
			TreeModel model;
			TreeIter iter;
			treeLanguage.Selection.GetSelected (out model, out iter);
			string sCulture = (string)model.GetValue (iter, 0);
			
			return sCulture;				
		}
		
		public void UpdatePrimaryLanguageDisplay ()
		{
			TreeIter iter = new TreeIter();
			if(_store.GetIterFirst(out iter))
			{
				do
				{
					string sCulture = (string)_store.GetValue(iter, 0);
					if(sCulture == PrimaryLanguage)
						_store.SetValue(iter, 1, colorPrimaryLanguage);
					else
						_store.SetValue(iter, 1, colorWhite);																			
				}
				while(_store.IterNext(ref iter));							
			} // if					
		}
		
		/// <summary>
		/// Sets the langauges.
		/// </summary>
		public void SetLangauges (CultureCollection collection)
		{
			_CultureCollection = collection;
			
			// create internal collection
			CreateInternalCollection (collection);
			
			// bind to the treeview
			BindTreeView ();	
			
		}
		
		private void CreateColumns ()
		{
			TreeViewColumn column = new TreeViewColumn ();
			CellRendererText renderer = new CellRendererText ();
			renderer.Editable = true;
			renderer.Edited += new EditedHandler (FileNameEdited);
			
			column.Clickable = true;
			column.Title = "Language Culture";
			column.PackStart (renderer, true);
			column.AddAttribute (renderer, "text", 0);
			column.AddAttribute (renderer, "background", 1);
			column.AddAttribute(renderer, "editable", 2);
			treeLanguage.AppendColumn (column);
															
			treeLanguage.Selection.Mode = SelectionMode.Single;					
			
		}
		
		private void BindTreeView ()
		{
			if (_store != null) {
				_store.Clear ();
				_store = null;
				treeLanguage.Model = null;
			}
						
			_store = new TreeStore (new Type[]{ typeof(string), typeof(string), typeof(bool), typeof(string)});
			
			TreeIter rootIter = _store.AppendNode ();
			_store.SetValues(rootIter, "Root", colorWhite);
			
			foreach (var culture in lstCultureList) {
				TreeIter cultureRow = _store.AppendValues (rootIter, culture.Name, colorWhite, false, culture.Culture);
				
				foreach (var file in culture.FileRecords) {
					TreeIter fileRow = _store.AppendValues (cultureRow, file.FileName, colorWhite, false, file.OriginalFilePath);
				}
			}
			
			treeLanguage.Model = _store;
  			treeLanguage.Selection.SelectIter (rootIter);						
		}

		void FileNameEdited (object o, EditedArgs args)
		{
			TreePath path = new TreePath (args.Path);
			TreeIter iter;
			_store.GetIter (out iter, path);
			
			string sKey = (string)_store.GetValue (iter, lKeyIndex);

			string cellValue = args.NewText;
			_store.SetValue (iter, lNameIndex, cellValue);	
			
			bool bFound = false;
			foreach (var culture in lstCultureList) {
				foreach (var file in culture.FileRecords) {
					if (file.OriginalFilePath == sKey) {
						file.FileName = cellValue;
						bFound = true;
						break;
					}
				}
				if (bFound)
					break;
			}
			
			
			if (FilenameChangedEvent != null) {
				FilenameChangedEvent (sKey, cellValue);
			}
			
			RaiseChangeOccuredEvent ();
		}
		
		/// <summary>
		/// Creates the internal collection.
		/// </summary>
		private void CreateInternalCollection (CultureCollection collection)
		{
			lstCultureList.Clear ();
			
			foreach (var culture in lstCultureList) {
				LangaugeCultureRecord cultRec = new LangaugeCultureRecord ();
				cultRec.Culture = culture.Culture;
				cultRec.Name = culture.Culture;
				
				foreach (var langFile in culture.FileRecords) {
					LanguageFileRecord fileRec = new LanguageFileRecord ();
					fileRec.Culture = culture.Culture;
					fileRec.Default = false;
					fileRec.FileName = langFile.FileName;
					fileRec.OriginalFilePath = langFile.OriginalFilePath;
					fileRec.RelativeFilePath = langFile.RelativeFilePath;
					
					cultRec.FileRecords.Add (fileRec);
				}
				
				lstCultureList.Add (cultRec);
			}			
		}
		
		private void EditCultureProperties (CultureRecord cultureRecord)
		{
/*			CulturePropertiesDialog dlg = new CulturePropertiesDialog ();
			dlg.EnglishName = cultureRecord.EnglishName;
			dlg.CultureName = cultureRecord.CultureName;
			ResponseType res = (ResponseType)dlg.Run ();
			if (res == ResponseType.Apply) {
				cultureRecord.EnglishName = dlg.EnglishName;
				cultureRecord.CultureName = dlg.CultureName;
				RaiseChangeOccuredEvent ();
			}
			dlg.Destroy ();*/
		}
		
		private void EditFileProperties (string sRootPath, LanguageFile file)
		{
			FilePropertiesDialog dlg = new FilePropertiesDialog ();
			dlg.RootPath = sRootPath;
			dlg.RelativePath = file.RelativePath;
			dlg.Filename = file.Filename;
			dlg.RenamingMode = enumRenamingMode.ChangeAsociatedFiles;
			ResponseType res = (ResponseType)dlg.Run ();
			if (res == ResponseType.Ok) {				
				
				string sRelativePath = System.IO.Path.Combine (file.RelativePath, file.Filename);
				if (dlg.RenamingMode == enumRenamingMode.CreateNewAsociation) {
					MappedFileCollection coll = _CultureCollection.FileMapperContainer.GetCollectionByFile (sRelativePath);
					if (coll != null)
						coll.Remove (sRelativePath);
					
					sRelativePath = System.IO.Path.Combine (dlg.RelativePath, dlg.Filename);
					_CultureCollection.FileMapperContainer.CreateNewCollection (sRelativePath);
					
				} else {
					
				}
				
				file.RelativePath = dlg.RelativePath;
				file.Filename = dlg.Filename;
			}
			
			dlg.Destroy ();						
		}
	
		
		/// <summary>
		/// Internal language class
		/// </summary>
		public class LangaugeCultureRecord
		{
			public List<LanguageFileRecord> FileRecords
			{ get; set; }
			
			public string Name
			{ get; set; }
			
			public string Culture
			{ get; set; }
			
			
			public LangaugeCultureRecord()
			{
				FileRecords = new List<LanguageFileRecord>();
			}
		
		}
		
		
		public class LanguageFileRecord
		{		
			public string Culture
			{ get; set; }
			
			public string OriginalFilePath
			{ get; set; }
			
			public string RelativeFilePath
			{ get; set; }
			
			public string FileName
			{ get; set; }
			
			public bool Default
			{ get; set; }
				}
	}
}

